﻿#ifndef IMODELPARSER_H
#define IMODELPARSER_H

#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonValue>

template <typename ModelType>
class IModelParser
{
public:
    explicit IModelParser() { m_lastError = ""; }

    // 从文件加载并解析
    ModelType loadFromFile(const QString &filename);

    // 从字符串加载并解析
    ModelType loadFromString(const QString &jsonString);

    // 转换成Json字符串
    virtual QString toString(const ModelType& model) = 0;

    // 获取最后一次的错误信息
    QString lastError() const { return m_lastError; }

protected:
    void setLastError(const QString& err) { m_lastError = err; }

    // 主解析函数：从 JSON 文档解析为 ModelType
    virtual ModelType parseFromJson(const QJsonObject &json) = 0;

private:
    QString m_lastError;
};

template<typename ModelType>
ModelType IModelParser<ModelType>::loadFromFile(const QString &filename)
{
    m_lastError = "";
    ModelType model;

    QFile file(filename);
    if (!file.open(QIODevice::ReadOnly)) {
        m_lastError = QObject::tr("Cannot open file: %1").arg(file.errorString());
        return model;
    }

    QByteArray data = file.readAll();
    file.close();

    QJsonParseError error;
    QJsonDocument doc = QJsonDocument::fromJson(data, &error);

    if (error.error != QJsonParseError::NoError) {
        m_lastError = QObject::tr("JSON parse failed: %1").arg(error.errorString());
        return model;
    }

    if (!doc.isObject()) {
        setLastError(QObject::tr("JSON doc is not object"));
        return model;
    }

    return parseFromJson(doc.object());
}

template<typename ModelType>
ModelType IModelParser<ModelType>::loadFromString(const QString &jsonString)
{
    m_lastError = "";

    QJsonParseError error;
    QJsonDocument doc = QJsonDocument::fromJson(jsonString.toUtf8(), &error);

    if (error.error != QJsonParseError::NoError) {
        m_lastError = QObject::tr("JSON parse failed: %1").arg(error.errorString());
        return ModelType();
    }

    if (!doc.isObject()) {
        setLastError(QObject::tr("JSON doc is not object"));
        return ModelType();
    }

    return parseFromJson(doc.object());
}

#endif // IMODELPARSER_H
